package neuronet.server.gui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.ListModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import neuronet.common.NeuroNetCom;
import neuronet.server.ClientsTableItem;
import neuronet.server.NeuroNetServer;

import org.apache.log4j.Logger;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class ServerFrame extends javax.swing.JFrame implements ListSelectionListener, ActionListener {

    private static final long serialVersionUID = 9092782660571620960L;

    private JButton exitjButton;
    private JLabel clientidLabel;
    private JLabel serverlogLabel;
    private JLabel serverPortLabel;
    private JLabel serverIPLabel;
    private JLabel lastactiveLabel;
    private JLabel clientTargetsLabel;
    private JLabel clieninfoLabel;
    private JLabel clientDataItemsLabel;
    private JTextField serverPortTextField;
    private JButton removeButton;
    private JButton resetButton;
    private JTextField serverIPTextField;
    private JTextField clientIDTextField;
    private JTextField clientDataItemsTextField;
    private JTextField clientLastActiveTextField;
    private JTextField clientTargetsTextField;
    private JTextArea clientInfoTextArea;
    private JTextArea serverLogTextArea;
    private JList clientsList;
    private JScrollPane serverLogScrollPane;

    // the server
    protected NeuroNetServer server;

    // log4j-Logger
    private static Logger logger = Logger.getLogger(ServerFrame.class);

    // Indices of selected clients
    private int selClientIndices[];

    private boolean onlineFlag = false;

    //    /**
    //    * Auto-generated main method to display this JFrame
    //    */
    //    public static void main(String[] args)
    //    {
    //	SwingUtilities.invokeLater(new Runnable()
    //	{
    //
    //	    public void run()
    //	    {
    //		ServerFrame inst = new ServerFrame();
    //		inst.setLocationRelativeTo(null);
    //		inst.setVisible(true);
    //	    }
    //	});
    //    }

    public ServerFrame(NeuroNetServer server)
    {
	super();
	this.server = server;
	initGUI();
	initUpdater();
	this.setTitle("Neuro-Net Server ");

    }

    private void initGUI()
    {
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	try
	{
	    GroupLayout thisLayout = new GroupLayout((JComponent) getContentPane());
	    getContentPane().setLayout(thisLayout);
	    {
		exitjButton = new JButton();
		exitjButton.setText("Exit");
		exitjButton.setActionCommand("exit");
		exitjButton.addActionListener(this);
	    }
	    {
		ListModel clientsjListModel = new DefaultComboBoxModel(new String[] { "Item One", "Item Two" });
		clientsList = new JList();
		clientsList.setModel(clientsjListModel);
		clientsList.addListSelectionListener(this);

	    }
	    {
		clientIDTextField = new JTextField();
	    }
	    {
		clientidLabel = new JLabel();
		clientidLabel.setText("Client ID");
	    }
	    {
		clieninfoLabel = new JLabel();
		clieninfoLabel.setText("Client Info");
	    }
	    {
		clientInfoTextArea = new JTextArea();
		clientInfoTextArea.setDoubleBuffered(true);
	    }
	    {
		clientTargetsLabel = new JLabel();
		clientTargetsLabel.setText("Targets");
	    }
	    {
		lastactiveLabel = new JLabel();
		lastactiveLabel.setText("Last Active");
	    }
	    {
		clientTargetsTextField = new JTextField();
	    }
	    {
		clientLastActiveTextField = new JTextField();
	    }
	    {
		clientDataItemsLabel = new JLabel();
		clientDataItemsLabel.setText("Data Items");
	    }
	    {
		clientDataItemsTextField = new JTextField();
	    }
	    {
		serverIPLabel = new JLabel();
		serverIPLabel.setText("Server IP");
		serverIPLabel.setHorizontalAlignment(SwingConstants.CENTER);
		serverIPLabel.setHorizontalTextPosition(SwingConstants.CENTER);
	    }
	    {
		serverIPTextField = new JTextField();
	    }
	    {
		serverPortLabel = new JLabel();
		serverPortLabel.setText("Server Port");
		serverPortLabel.setHorizontalAlignment(SwingConstants.CENTER);
		serverPortLabel.setHorizontalTextPosition(SwingConstants.CENTER);
	    }
	    {
		serverPortTextField = new JTextField();
	    }
	    {
		serverlogLabel = new JLabel();
		serverlogLabel.setText("Server Log");
	    }
	    {
		serverLogTextArea = new JTextArea();
		serverLogScrollPane = new JScrollPane(serverLogTextArea);
		serverLogScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		serverLogScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	    }
	    {
		resetButton = new JButton();
		resetButton.setText("Reset");
		resetButton.setActionCommand("reset");
		resetButton.addActionListener(this);
	    }
	    {
		removeButton = new JButton();
		removeButton.setText("Remove");
		removeButton.setActionCommand("remove");
		removeButton.addActionListener(this);
	    }
	    thisLayout.setVerticalGroup(thisLayout.createSequentialGroup()
	    	.addContainerGap()
	    	.addGroup(thisLayout.createParallelGroup()
	    	    .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	        .addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	    	            .addComponent(clientIDTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(clientidLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(resetButton, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	        .addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	    	            .addComponent(clientTargetsTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(clientTargetsLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(removeButton, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	        .addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	    	            .addComponent(clientLastActiveTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(lastactiveLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE))
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	        .addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	    	            .addComponent(clientDataItemsTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
	    	            .addComponent(clientDataItemsLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE))
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
	    	        .addComponent(clieninfoLabel, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	        .addComponent(clientInfoTextArea, GroupLayout.PREFERRED_SIZE, 84, GroupLayout.PREFERRED_SIZE))
	    	    .addComponent(clientsList, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 227, GroupLayout.PREFERRED_SIZE))
	    	.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
	    	.addComponent(serverlogLabel, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
	    	.addComponent(serverLogScrollPane, 0, 399, Short.MAX_VALUE)
	    	.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	.addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	    	    .addComponent(serverIPLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 26, GroupLayout.PREFERRED_SIZE)
	    	    .addComponent(exitjButton, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 26, GroupLayout.PREFERRED_SIZE)
	    	    .addComponent(serverIPTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 26, GroupLayout.PREFERRED_SIZE)
	    	    .addComponent(serverPortLabel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 26, GroupLayout.PREFERRED_SIZE)
	    	    .addComponent(serverPortTextField, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 26, GroupLayout.PREFERRED_SIZE))
	    	.addContainerGap());
	    thisLayout.setHorizontalGroup(thisLayout.createSequentialGroup()
	    	.addContainerGap()
	    	.addGroup(thisLayout.createParallelGroup()
	    	    .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	        .addGroup(thisLayout.createParallelGroup()
	    	            .addComponent(serverIPLabel, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE)
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(serverlogLabel, GroupLayout.PREFERRED_SIZE, 77, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(14)))
	    	        .addComponent(serverIPTextField, GroupLayout.PREFERRED_SIZE, 162, GroupLayout.PREFERRED_SIZE)
	    	        .addGroup(thisLayout.createParallelGroup()
	    	            .addGroup(thisLayout.createSequentialGroup()
	    	                .addGroup(thisLayout.createParallelGroup()
	    	                    .addComponent(clientDataItemsTextField, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 165, GroupLayout.PREFERRED_SIZE)
	    	                    .addComponent(clientLastActiveTextField, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 165, GroupLayout.PREFERRED_SIZE)
	    	                    .addComponent(clientTargetsTextField, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 165, GroupLayout.PREFERRED_SIZE)
	    	                    .addComponent(clientIDTextField, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 165, GroupLayout.PREFERRED_SIZE))
	    	                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
	    	                .addGroup(thisLayout.createParallelGroup()
	    	                    .addComponent(removeButton, GroupLayout.Alignment.LEADING, 0, 117, Short.MAX_VALUE)
	    	                    .addComponent(resetButton, GroupLayout.Alignment.LEADING, 0, 117, Short.MAX_VALUE)))
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addPreferredGap(clientDataItemsTextField, serverPortLabel, LayoutStyle.ComponentPlacement.INDENT)
	    	                .addComponent(serverPortLabel, GroupLayout.PREFERRED_SIZE, 89, GroupLayout.PREFERRED_SIZE)
	    	                .addComponent(serverPortTextField, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)
	    	                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
	    	                .addComponent(exitjButton, 0, 78, Short.MAX_VALUE)
	    	                .addGap(0, 11, GroupLayout.PREFERRED_SIZE))))
	    	    .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	        .addComponent(clientsList, GroupLayout.PREFERRED_SIZE, 141, GroupLayout.PREFERRED_SIZE)
	    	        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
	    	        .addGroup(thisLayout.createParallelGroup()
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(clientDataItemsLabel, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(0, 300, Short.MAX_VALUE))
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(lastactiveLabel, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(0, 300, Short.MAX_VALUE))
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(clientTargetsLabel, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(0, 300, Short.MAX_VALUE))
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(clientidLabel, GroupLayout.PREFERRED_SIZE, 79, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(0, 303, Short.MAX_VALUE))
	    	            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	                .addComponent(clieninfoLabel, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE)
	    	                .addGap(0, 300, Short.MAX_VALUE))
	    	            .addComponent(clientInfoTextArea, GroupLayout.Alignment.LEADING, 0, 382, Short.MAX_VALUE))
	    	        .addGap(12))
	    	    .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
	    	        .addComponent(serverLogScrollPane, 0, 535, Short.MAX_VALUE)
	    	        .addGap(12))));
	    thisLayout.linkSize(SwingConstants.VERTICAL, new Component[] {serverIPLabel, serverIPTextField, serverPortLabel, serverPortTextField, exitjButton});
	    thisLayout.linkSize(SwingConstants.VERTICAL, new Component[] {clientDataItemsLabel, clientDataItemsTextField, clientLastActiveTextField, clientTargetsTextField, clientIDTextField, clientidLabel, clientTargetsLabel, lastactiveLabel});
	    pack();
	    this.setSize(575, 753);
	}
	catch (Exception e)
	{
	    //add your error handling code here
	    e.printStackTrace();
	}
    }

    /**
     * Method for creation of an Updater to refresh GUI with new information from server.
     */
    private void initUpdater()
    {

	Timer timer;

	timer = new Timer();
	timer.schedule(new ServerRemindTask(this), 1000, 1000);

    }

    class ServerRemindTask extends TimerTask {

	ServerFrame server;

	public ServerRemindTask(ServerFrame server)
	{
	    this.server = server;
	}

	public void run()
	{
	    //	    logger.info("Time's up!");
	    server.updateData();
	}
    }

    public void updateData()
    {
	//	    logger.info("Refreshing server frame ...");

	// Refresh clientslist
	Object[] sel = clientsList.getSelectedValues();
	Vector<String> newObjs = NeuroNetServer.getClientList();
	clientsList.setListData(newObjs);
	for (int i = 0; i < sel.length; i++)
	{
	    if(newObjs.contains((String)sel[i]))
		clientsList.setSelectedValue((String)sel[i], false);
	}
	
	// activate / deactivate Textfields

	serverIPTextField.setEditable(false);
	serverPortTextField.setEditable(false);

	clientIDTextField.setEditable(false);
	clientDataItemsTextField.setEditable(false);
	clientLastActiveTextField.setEditable(false);
	clientTargetsTextField.setEditable(false);
	clientInfoTextArea.setEditable(false);
	serverLogTextArea.setEditable(false);
	
	//	ClientInfo serverInfo = client.getServerInfoObject();
	//	ClientInfo clientInfo = client.getClientInfoObject(client.getClientID());
	//	
	//	serverlogTextField.setText(serverInfo.getLog());
	//	serverIPTextField.setText(serverInfo.getIP());
	//	serverPortTextField.setText(serverInfo.getPort());

	//	lastactiveTextField.setText(clientInfo.getLast());
	//	
	//	clientportTextField.setText(clientInfo.getPort());
	//	clientinfoTextField.setText(clientInfo.getInfo());
	//	clientipTextField.setText(clientInfo.getIP());
	//	clientidTextField.setText(clientInfo.getID());

    }

    public void setServerData(String ip, int port)
    {
	serverPortTextField.setText(port + "");
	serverIPTextField.setText(ip + "");

    }

    public void addLogMessage(String mess)
    {
	String text = serverLogTextArea.getText();
	text += " \n\r " + mess;
	serverLogTextArea.setText(text);
	serverLogTextArea.setCaretPosition(text.length());
    }

    @Override
    public void valueChanged(ListSelectionEvent e)
    {
	logger.info("First index: " + e.getFirstIndex());
	logger.info("Last index: " + e.getLastIndex());
	boolean adjust = e.getValueIsAdjusting();
	logger.info("Adjusting? " + adjust);
	if (!adjust)
	{
	    JList list = (JList) e.getSource();
	    selClientIndices = list.getSelectedIndices();
	    Object selectionValues[] = list.getSelectedValues();
	    for (int i = 0, n = selClientIndices.length; i < n; i++)
	    {
		if (i == 0)
		{
		    logger.info("  Selections: ");
		}
		logger.info(selClientIndices[i] + "/" + selectionValues[i] + " ");
	    }
	}
	if (selClientIndices != null && selClientIndices.length > 0)
	{
	    ClientsTableItem lastIndexClient = NeuroNetServer.getClientItem((String) clientsList.getSelectedValues()[clientsList.getSelectedValues().length - 1]);

	    clientIDTextField.setText(lastIndexClient.getClientID());
	    clientInfoTextArea.setText(lastIndexClient.getClientInfo());
	    clientTargetsTextField.setText(NeuroNetCom.stringVectorToString(lastIndexClient.getDataTargets(), ","));
	    clientDataItemsTextField.setText(NeuroNetCom.stringVectorToString(lastIndexClient.getDataItems(), ","));
	    clientLastActiveTextField.setText(lastIndexClient.getClientLast());
	}
	//	else
	//	    {
	//	    clientidTextField.setText("");
	//	    clientinfoTextField.setText("");
	//	    }
    }

    @Override
    public void actionPerformed(ActionEvent ae)
    {
	if (ae.getActionCommand().equals("exit"))
	{
	    addLogMessage("Exiting Server");
	    logger.info("exitjButton.actionPerformed, event=" + ae);
	    // TODO: call Destructor of NeuroNetServer
	    System.exit(0);
	}
	if (ae.getActionCommand().equals("reset"))
	{
	    logger.info("resetting Server");
	    addLogMessage("resetting Server");
	    NeuroNetServer.reset();
	}
	if (ae.getActionCommand().equals("remove"))
	{
	    Object selectionValues[] = clientsList.getSelectedValues();
	    for (int i = 0, n = selectionValues.length; i < n; i++)
	    {
		String clientid = (String)selectionValues[i];
		if(clientid.equals(NeuroNetServer.getServerID()))
		{
		    logger.info("Can't remove Server: " + clientid);
		    addLogMessage("Can't remove Server: " + clientid);
		}
		else
		{
		    logger.info("Removing Client: " + clientid);
		    addLogMessage("Removing Clients: " + clientid);
		    NeuroNetServer.removeClient(clientid, NeuroNetServer.getClientItem(clientid).getClientKey());
		}
	    }

	    
	}

    }
}
